<!--
 * @Date: 2024-07-31 10:07:21
 * @Author: LiSong
 * @LastEditors: LiSong
 * @LastEditTime: 2025-05-08 11:14:56
 * @Description: 代码编辑器弹窗
-->
<template>
  <vxe-modal
    :="modalAttrs"
    v-model="modelStore.visible"
    @close="handleClose"
  >
    <div class="code-editor-container">
      <div v-show="showSwitch" class="content-kind">
        <span>数据类型：</span>
        <el-switch :="switchAttrs" v-model="modelStore.codeIsFunc"/>
      </div>
      <el-alert :title="props.frontAlert" v-show="alertEnabled" :="alertAttrs"/>
      <AceCodeEditor
        class="code-editor-panel"
        :mode="modelStore.codeIsFunc ? 'javascript' : defaultMode"
        v-model="modelStore.codeContent"
      />
      <el-alert :title="props.behindAlert" v-show="alertEnabled" :="alertAttrs"/>
    </div>
    <template #footer>
      <slot v-if="$slots.footer" name="footer" />
      <div v-else class="dialog-footer">
        <el-button size="default" @click="handleClose">取消</el-button>
        <el-button size="default" type="primary" @click="handleConfirm">确定</el-button>
      </div>
    </template>
  </vxe-modal>
</template>

<script setup>
import XEUtils from 'xe-utils'
import { VfMessage } from '@/utils/vf-utils'
import { AceCodeEditor } from '@/components/vf-editor'
import { reactive, computed, watch } from 'vue';
import { baseAttrs } from '@/components/dialogs/cfg/base-cofig.js'

const emits = defineEmits([
  'close', 'confirm'
]);

// 传递参数定义
const props = defineProps({
  // 弹窗标题
  title: { type: String, default: '代码编辑' },
  // 是否显示提示
  showAlert: { type: Boolean, default: true },
  // 是否显示切换按钮
  showSwitch: { type: Boolean, default: false },
  // switch的标识
  inactiveText: { type: String, default: '对象' },
  // 前置提示
  frontAlert: { type: String, default: 'function (this) {' },
  // 后置提示
  behindAlert: { type: String, default: '}' },
  // 编辑的内容
  editorValue: { type: String, default: '' },
  // 默认模式
  defaultMode: { type: String, default: 'javascript' }
});

// 弹窗的属性
const modalAttrs = reactive({
  ...baseAttrs,
  title: props.title,
  width: '85%',
  height: '80%',
  resize: false,
  className: `${baseAttrs.className} vf-setting-dialog `,
})
// 编辑器内容数据集
const modelStore = reactive({
  visible: false,
  funcMark: 'func:',
  codeIsFunc: props.showAlert,
  codeContent: '',
})
watch (
  () => props.title,
  (nv) => {
    modalAttrs.title = nv
  },
  { deep: true, immediate: false }
)
/**
 * 打开弹窗的方法
 * 
 * @param content 编写内容
 */
const handleOpen = (content) => {
  modelStore.visible = true
  const parseData = parseContent(content, true)
  modelStore.codeIsFunc = parseData.isFunc
  modelStore.codeContent = parseData.result
}
/**
 * 关闭弹窗的方法
 */
const handleClose = () => {
  modelStore.codeIsFunc = props.showAlert
  modelStore.codeContent = ''
  modelStore.visible = false
}
/**
 * 确定按钮点击方法
 */
const handleConfirm = () => {
  const parseData = parseContent(modelStore.codeContent, false)
  emits('confirm', parseData.result);
  handleClose()
};
/**
 * 转换内容
 * 
 * @param content 内容
 * @param reverse 是否方向转换
 */
const parseContent = (content, reverse=false) => {
  let result = content
  let isFunc = false
  let funcMark = 'func:'
  if (reverse) {
    // 如果是对象数据，则不为方法定义内容
    if (content && XEUtils.isObject(content)) {
      isFunc = false
      result = JSON.stringify(content, null, '  ')
    } else if (content && XEUtils.isString(content)) {
      // 如果以方法标识开头
      if (content.startsWith(funcMark)) {
        isFunc = true
        result = content.replace(funcMark, '')
      } else {
        isFunc = false
        result = content
      }
    } else {
      isFunc = props.showAlert
    }
  } else {
    if (content && modelStore.codeIsFunc) {
      result = `${funcMark}${content}`
    } else {
      try {
        if (props.defaultMode === 'text') {
          result = content
        } else {
          result = content ? JSON.parse(content) : '';
        }
      } catch(err) {
        result = ''
        VfMessage.error('参数解析出错，请确认参数信息！');
      }
    }
  }
  return {
    result, isFunc
  }
}
// 提示子组件的属性
const alertAttrs = reactive({
  type: 'info',
  style: { padding: '5px 10px' },
  closable: false,
});
// 提示组件是否启用
const alertEnabled = computed(() => {
  if (props.showSwitch) {
    return props.showAlert && modelStore.codeIsFunc
  } else {
    return modelStore.codeIsFunc
  }
})
// 切换组件的属性
const switchAttrs = computed(() => {
  return {
    size: 'default',
    class: 'params-kind-switch',
    inlinePrompt: true,
    activeText: '方法',
    inactiveText: props.inactiveText
  }
})

defineExpose({
  handleOpen
});
</script>

<style lang="scss" scoped>
.code-editor-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  :deep(.code-editor-panel) {
    flex: 1;
    height: 0;
  }
  .content-kind {
    padding: 5px 8px
  }
}
:deep(.el-alert) {
  border: none !important;
  border-radius: unset;
}
.params-kind-switch {
  --el-switch-on-color: #409eff;
  --el-switch-off-color: #13ce66;
}
</style>
<style lang="scss">
.code-editor-modal {
  .vxe-modal--content {
    padding: 0 !important;
  }
}
</style>
